package indi.cc.demo.validator.aspect;

import indi.cc.demo.validator.exception.BasicException;
import indi.cc.demo.validator.message.MessageResponse;
import indi.cc.demo.validator.message.MessageType;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;

import java.util.ArrayList;
import java.util.List;

@Aspect
@Component
public class ValidatorAspect {
    @Pointcut(value = "execution(public * indi.cc.demo.validator.controller..*.*(..))")
    public void validatorPointcut(){}

    @Before(value = "validatorPointcut()")
    public void doBefore(){
        System.out.println("111111111111");
    }

    @Around(value = "validatorPointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around...........");
        Object[] args = pjp.getArgs();
        BindingResult result;
        String errorMessage = "";
        List<MessageResponse> messageList = new ArrayList<>();
        for (Object arg : args) {
            if (hasErrorInBindResult(arg)) {
                result = (BindingResult) arg;
                for (FieldError fieldError : result.getFieldErrors()) {
                    return new ResponseEntity<>(fieldError.getDefaultMessage(), HttpStatus.BAD_REQUEST);
//                    messageList.add(new MessageResponse(fieldError.getDefaultMessage(), MessageType.E));
//                    errorMessage += fieldError.getDefaultMessage() + " ";
                }
            }
        }
//        if (!messageList.isEmpty()) {
//            throw new BasicException(messageList);
//        }

        return pjp.proceed();
    }

    private boolean hasErrorInBindResult(Object arg) {
        return arg instanceof BindingResult && ((BindingResult) arg).hasErrors();
    }
}
